package com.yanqu.road.entity.activity.sonhai.data;

import com.yanqu.road.entity.DataObject;
import com.yanqu.road.entity.DataStatus;
import com.yanqu.road.entity.FieldTypeAnnotation;
import com.yanqu.road.entity.activity.sonhai.enums.SonHaiDieFlagEnum;
import com.yanqu.road.entity.activity.sonhai.enums.SonHaiPlotTypeEnum;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@FieldTypeAnnotation(tableName = "t_c_activity_son_hai_user_data")
public class SonHaiUserData extends DataObject {

    @FieldTypeAnnotation(desc = "活动ID", select = true, update = true)
    private int activityId;

    @FieldTypeAnnotation(desc = "分组ID", select = true, update = true)
    private int groupId;

    @FieldTypeAnnotation(desc = "玩家ID", select = true, update = true)
    private long userId;

    @FieldTypeAnnotation(desc = "队伍ID")
    private int teamId;

    @FieldTypeAnnotation(desc = "玩家区服ID")
    private long serverId;

    @FieldTypeAnnotation(desc = "体力")
    private int energy;

    @FieldTypeAnnotation(desc = "体力恢复时间")
    private long energyRestoreTime;

    @FieldTypeAnnotation(desc = "积分")
    private long score;

    @FieldTypeAnnotation(desc = "山海灵气")
    private long auraScore;

    @FieldTypeAnnotation(desc = "圣兽降临次数")
    private int buffComeNum;

    @FieldTypeAnnotation(desc = "下一次圣兽降临需要消耗的体力")
    private int nextBuffComeNeedEnergy;

    @FieldTypeAnnotation(desc = "待选择的buff列表")
    private List<SonHaiWaitSelectBuffData> waitSelectBuffList = new ArrayList<>();

    @FieldTypeAnnotation(desc = "圣兽buff。k：buffId,v：buff")
    private Map<Integer, SonHaiBuffData> buffMap = new ConcurrentHashMap<>();

    @FieldTypeAnnotation(desc = "当前所在区域")
    private int regionId;

    @FieldTypeAnnotation(desc = "当前所在区域x坐标")
    private int x;

    @FieldTypeAnnotation(desc = "当前所在区域y坐标")
    private int y;

    @FieldTypeAnnotation(desc = "pvp杀人数（连杀数，死亡清除）")
    private int pvpKillNum;

    @FieldTypeAnnotation(desc = "pvp可被攻击次数")
    private int pvpCanBeAttNum;

    @FieldTypeAnnotation(desc = "是否死亡，0：未死亡，1：死亡")
    private int dieFlag;

    @FieldTypeAnnotation(desc = "死亡信息")
    private SonHaiUserDieData dieData;

    @FieldTypeAnnotation(desc = "门客天赋技能战力加成rate")
    private int talentAddition;

    @FieldTypeAnnotation(desc = "前30门客战力")
    private long power;

    @FieldTypeAnnotation(desc = "总血量")
    private long allBlood;

    @FieldTypeAnnotation(desc = "减少的血量")
    private long reBlood;

    @FieldTypeAnnotation(desc = "掉血详情MAP,k:玩家ID")
    private Map<Long, SonHaiReBloodInfo> reBloodInfoMap = new ConcurrentHashMap<>();

    @FieldTypeAnnotation(desc = "是否选择过区域")
    private int selectRegionFlag;

    @FieldTypeAnnotation(desc = "协助次数")
    private int helpNum;

    @FieldTypeAnnotation(desc = "每消耗N1体力恢复N2协助次数 的 计数器")
    private int helpNumCount;

    @FieldTypeAnnotation(desc = "语言")
    private String language;

    @FieldTypeAnnotation(desc = "创建时间")
    private long createTime;

    public SonHaiUserData() {}

    public SonHaiUserData(SonHaiUserData userData) {
        this.activityId = userData.getActivityId();
        this.groupId = userData.getGroupId();
        this.userId = userData.getUserId();
        this.teamId = userData.getTeamId();
        this.serverId = userData.getServerId();
        this.energy = userData.getEnergy();
        this.regionId = userData.getRegionId();
        this.energyRestoreTime = userData.getEnergyRestoreTime();
        this.score = userData.getScore();
        this.auraScore = userData.getAuraScore();
        this.x = userData.getX();
        this.y = userData.getY();
        this.buffComeNum = userData.getBuffComeNum();
        this.nextBuffComeNeedEnergy = userData.getNextBuffComeNeedEnergy();
        this.waitSelectBuffList = userData.getWaitSelectBuffList();
        this.buffMap = userData.getBuffMap();
        this.pvpKillNum = userData.getPvpKillNum();
        this.pvpCanBeAttNum = userData.getPvpCanBeAttNum();
        this.dieFlag = userData.getDieFlag();
        this.dieData = userData.getDieData();
        this.talentAddition = userData.getTalentAddition();
        this.power = userData.getPower();
        this.allBlood = userData.getAllBlood();
        this.reBlood = userData.getReBlood();
        this.reBloodInfoMap = userData.getReBloodInfoMap();
        this.selectRegionFlag = userData.getSelectRegionFlag();
        this.helpNum = userData.getHelpNum();
        this.helpNumCount = userData.getHelpNumCount();
        this.language = userData.getLanguage();
        this.createTime = userData.getCreateTime();
    }

    public SonHaiUserData(int activityId, int groupId, long userId, int teamId, long serverId, int energy, int nextBuffComeNeedEnergy, int pvpCanBeAttNum, long power, int helpNum, String language) {
        this.activityId = activityId;
        this.groupId = groupId;
        this.userId = userId;
        this.teamId = teamId;
        this.serverId = serverId;
        this.energy = energy;
        this.energyRestoreTime = 0;
        this.score = 0;
        this.auraScore = 0;
        this.x = 0;
        this.y = 0;
        this.buffComeNum = 0;
        this.nextBuffComeNeedEnergy = nextBuffComeNeedEnergy;
        this.pvpKillNum = 0;
        this.pvpCanBeAttNum = pvpCanBeAttNum;
        this.dieFlag = SonHaiDieFlagEnum.DIE_NOT.getType();
        this.talentAddition = 0;
        this.power = power;
        this.allBlood = 0;
        this.reBlood = 0;
        this.selectRegionFlag = 0;
        this.helpNum = helpNum;
        this.helpNumCount = 0;
        this.language = language;
        this.createTime = System.currentTimeMillis();
        setInsertOption();
    }

    public int getActivityId() {
        return activityId;
    }

    public void setActivityId(int activityId) {
        if (this.activityId != activityId) {
            this.activityId = activityId;
            setOp(DataStatus.Update);
        }
    }

    public int getGroupId() {
        return groupId;
    }

    public void setGroupId(int groupId) {
        if (this.groupId != groupId) {
            this.groupId = groupId;
            setOp(DataStatus.Update);
        }
    }

    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        if (this.userId != userId) {
            this.userId = userId;
            setOp(DataStatus.Update);
        }
    }

    public int getTeamId() {
        return teamId;
    }

    public void setTeamId(int teamId) {
        if (this.teamId != teamId) {
            this.teamId = teamId;
            setOp(DataStatus.Update);
        }
    }

    public long getServerId() {
        return serverId;
    }

    public void setServerId(long serverId) {
        if (this.serverId != serverId) {
            this.serverId = serverId;
            setOp(DataStatus.Update);
        }
    }

    public int getEnergy() {
        return energy;
    }

    public void setEnergy(int energy) {
        if (this.energy != energy) {
            this.energy = energy;
            setOp(DataStatus.Update);
        }
    }

    public long getEnergyRestoreTime() {
        return energyRestoreTime;
    }

    public void setEnergyRestoreTime(long energyRestoreTime) {
        if (this.energyRestoreTime != energyRestoreTime) {
            this.energyRestoreTime = energyRestoreTime;
            setOp(DataStatus.Update);
        }
    }

    public long getScore() {
        return score;
    }

    public void setScore(long score) {
        if (this.score != score) {
            this.score = score;
            setOp(DataStatus.Update);
        }
    }

    public long getAuraScore() {
        return auraScore;
    }

    public void setAuraScore(long auraScore) {
        if (this.auraScore != auraScore) {
            this.auraScore = auraScore;
            setOp(DataStatus.Update);
        }
    }

    public Map<Integer, SonHaiBuffData> getBuffMap() {
        return buffMap;
    }

    public void setBuffMap(Map<Integer, SonHaiBuffData> buffMap) {
        this.buffMap = buffMap;
    }

    public SonHaiBuffData getBuff(int buffId) {
        return this.buffMap.get(buffId);
    }

    public void addBuff(SonHaiBuffData buff) {
        this.buffMap.put(buff.getBuffId(), buff);
        setOp(DataStatus.Update);
    }

    public int getBuffComeNum() {
        return buffComeNum;
    }

    public void setBuffComeNum(int buffComeNum) {
        if (this.buffComeNum != buffComeNum) {
            this.buffComeNum = buffComeNum;
            setOp(DataStatus.Update);
        }
    }

    public int getNextBuffComeNeedEnergy() {
        return nextBuffComeNeedEnergy;
    }

    public void setNextBuffComeNeedEnergy(int nextBuffComeNeedEnergy) {
        if (this.nextBuffComeNeedEnergy != nextBuffComeNeedEnergy) {
            this.nextBuffComeNeedEnergy = nextBuffComeNeedEnergy;
            setOp(DataStatus.Update);
        }
    }


    public List<SonHaiWaitSelectBuffData> getWaitSelectBuffList() {
        return waitSelectBuffList;
    }

    public void setWaitSelectBuffList(List<SonHaiWaitSelectBuffData> waitSelectBuffList) {
        this.waitSelectBuffList = waitSelectBuffList;
    }

    public void addWaitSelectBuff(Set<Integer> waitSelectBuff) {
        SonHaiWaitSelectBuffData waitSelectBuffData = new SonHaiWaitSelectBuffData(waitSelectBuff);
        this.waitSelectBuffList.add(waitSelectBuffData);
        setOp(DataStatus.Update);
    }

    public void removeFirstWaitSelectBuff() {
        if (!this.waitSelectBuffList.isEmpty()) {
            this.waitSelectBuffList.remove(0);
            setOp(DataStatus.Update);
        }
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        if (this.x != x) {
            this.x = x;
            setOp(DataStatus.Update);
        }
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        if (this.y != y) {
            this.y = y;
            setOp(DataStatus.Update);
        }
    }

    public int getRegionId() {
        return regionId;
    }

    public void setRegionId(int regionId) {
        if (this.regionId != regionId) {
            this.regionId = regionId;
            setOp(DataStatus.Update);
        }
    }

    public int getPvpKillNum() {
        return pvpKillNum;
    }

    public void setPvpKillNum(int pvpKillNum) {
        if (this.pvpKillNum != pvpKillNum) {
            this.pvpKillNum = pvpKillNum;
            setOp(DataStatus.Update);
        }
    }

    public int getPvpCanBeAttNum() {
        return pvpCanBeAttNum;
    }

    public void setPvpCanBeAttNum(int pvpCanBeAttNum) {
        if (this.pvpCanBeAttNum != pvpCanBeAttNum) {
            this.pvpCanBeAttNum = pvpCanBeAttNum;
            setOp(DataStatus.Update);
        }
    }

    public int getDieFlag() {
        return dieFlag;
    }

    public void setDieFlag(int dieFlag) {
        if (this.dieFlag != dieFlag) {
            this.dieFlag = dieFlag;
            setOp(DataStatus.Update);
        }
    }

    public SonHaiUserDieData getDieData() {
        return dieData;
    }

    public void setDieData(SonHaiUserDieData dieData) {
        this.dieData = dieData;
        setOp(DataStatus.Update);
    }

    public int getTalentAddition() {
        return talentAddition;
    }

    public void setTalentAddition(int talentAddition) {
        if (this.talentAddition != talentAddition) {
            this.talentAddition = talentAddition;
            setOp(DataStatus.Update);
        }
    }

    public long getPower() {
        return power;
    }

    public void setPower(long power) {
        if (this.power != power) {
            this.power = power;
            setOp(DataStatus.Update);
        }
    }

    public long getAllBlood() {
        return allBlood;
    }

    public void setAllBlood(long allBlood) {
        if (this.allBlood != allBlood) {
            this.allBlood = allBlood;
            setOp(DataStatus.Update);
        }
    }

    public long getReBlood() {
        return reBlood;
    }

    public void setReBlood(long reBlood) {
        if (this.reBlood != reBlood) {
            this.reBlood = reBlood;
            setOp(DataStatus.Update);
        }
    }

    public Map<Long, SonHaiReBloodInfo> getReBloodInfoMap() {
        return reBloodInfoMap;
    }

    public void setReBloodInfoMap(Map<Long, SonHaiReBloodInfo> reBloodInfoMap) {
        this.reBloodInfoMap = reBloodInfoMap;
        setOp(DataStatus.Update);
    }

    /**
     * 添加掉血
     * @param userId
     * @param reBlood
     */
    public synchronized void addReBlood(long userId, long reBlood) {
        //掉血
        this.reBlood += reBlood;
        //掉血明细
        SonHaiReBloodInfo info = this.reBloodInfoMap.computeIfAbsent(userId, k -> new SonHaiReBloodInfo());
        info.setUserId(userId);
        info.addReBlood(reBlood);
        info.setTime(System.currentTimeMillis());
        setOp(DataStatus.Update);
    }

    /**
     * 恢复血量
     * @param addBlood
     */
    public synchronized void addBlood(long addBlood) {
        if (addBlood > this.reBlood) {
            this.reBlood = 0;
        } else {
            this.reBlood = this.reBlood - addBlood;
        }
        setOp(DataStatus.Update);
    }

    public int getSelectRegionFlag() {
        return selectRegionFlag;
    }

    public void setSelectRegionFlag(int selectRegionFlag) {
        if (this.selectRegionFlag != selectRegionFlag) {
            this.selectRegionFlag = selectRegionFlag;
            setOp(DataStatus.Update);
        }
    }

    public int getHelpNum() {
        return helpNum;
    }

    public void setHelpNum(int helpNum) {
        if (this.helpNum != helpNum) {
            this.helpNum = helpNum;
            setOp(DataStatus.Update);
        }
    }

    public int getHelpNumCount() {
        return helpNumCount;
    }

    public void setHelpNumCount(int helpNumCount) {
        if (this.helpNumCount != helpNumCount) {
            this.helpNumCount = helpNumCount;
            setOp(DataStatus.Update);
        }
    }

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        if (!Objects.equals(this.language, language)) {
            this.language = language;
            setOp(DataStatus.Update);
        }
    }

    public long getCreateTime() {
        return createTime;
    }

    public void setCreateTime(long createTime) {
        if (this.createTime != createTime) {
            this.createTime = createTime;
            setOp(DataStatus.Update);
        }
    }
}
